// @ts-nocheck
import axios, { AxiosInstance, AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios';
import { DateRangePicker, MessagePlugin } from 'tdesign-vue-next';
import { setAuthorization, getHeardToken, getHeardXtoken, setMd5Info, removeAuthorization } from './utils';
import router from '../router/index';

// import {} from ""
const autoLogin = () => {};
// 是否正在刷新的标记
let isRefreshing = false;
// 重试队列，每一项将是一个待执行的函数形式
let requests = [];
interface Result {
  code: number;
  msg: string;
  data?: any;
  errors?: any;
  extras?: any;
  statusCode: number;
  succeeded: boolean;
  timestamp: number;
}
type PersonHeard = {
  'access-token': string;
  'x-access-token': string;
  'content-type': string;
  environment: string;
};
// 请求响应参数，包含data
interface ResultData<T = any> extends Result {
  data?: T;
}

const URL: string = 'https://taniayi.elev.top';
enum RequestEnums {
  TIMEOUT = 20000,
  OVERDUE = 401, // 登录失效
  FAIL = 999, // 请求失败
  SUCCESS = 200, // 请求成功
}
const config = {
  // 默认地址
  baseURL: URL as string,
  // 设置超时时间
  timeout: RequestEnums.TIMEOUT as number,
  // 跨域时候允许携带凭证 
  withCredentials: false,
}; 

class RequestHttp {
  // 定义成员变量并指定类型
  service: AxiosInstance;
  public constructor(config: AxiosRequestConfig) {
    // 实例化axios
    this.service = axios.create(config);
    /**
     * 请求拦截器
     * 客户端发送请求 -> [请求拦截器] -> 服务器
     * token校验(JWT) : 接受服务器返回的token,存储到vuex/pinia/本地储存当中
     */

    this.service.interceptors.request.use(
      (config: any) => {
        //AxiosRequestConfig
        var configs: AxiosRequestConfig = config;

        return {
          ...configs, 
          headers: {
            'Content-Type': 'application/json;charset=utf-8',
            
          },
        };
      },
      (error: AxiosError) => {
        // 请求报错
        Promise.reject(error);
      },
    );
    /**
     * 响应拦截器
     * 服务器换返回信息 -> [拦截统一处理] -> 客户端JS获取到信息
     */

    this.service.interceptors.response.use(
      (response: AxiosResponse) => {
        // console.log(response.headers, '头部');
        let heardInfo: any = response.headers;
        setAuthorization(heardInfo);
        // console.log(response);
        const { data, config } = response; // 解构
        if (data.code !== 0) {
          Promise.reject(data);
        }

        // if (data.statusCode === RequestEnums.OVERDUE) {
        //   //
        //   // return Promise.reject(data);
        // } // 全局错误信息拦截（防止下载文件得时候返回数据流，没有code，直接报错）
        // if (data.statusCode && data.statusCode !== RequestEnums.SUCCESS) {
        //   MessagePlugin.error({ content: data.errors }); // 此处也可以使用组件提示报错信息
        //   return Promise.reject(data);
        // }

        return data;
      },
      (error: AxiosError) => {
        const { response, responseURL } = error;
        MessagePlugin.error(JSON.stringify(response.status));
      },
    ); 
  }
  handleCode(code: number, err?: any): void {
    let url = window.location.href;

    switch (code) {
      case 403:
        // removeAuthorization();

        router.push({ path: '/login', query: { redirect: url } });
        MessagePlugin.error('操作失败，请重新登录');
        break;
      case 401:
        // removeAuthorization();

        router.push({ path: '/login', query: { redirect: url } });
        MessagePlugin.error('操作失败，请重新登录');
        break;
      case 500:
        if (err && err === '未能获取主键信息') {
        }
        // removeAuthorization();
        // let url=window.location.href
        // router.push({ path: '/login', query: { redirect: url }});

        break;
      default:
        if (typeof err === 'string') {
          MessagePlugin.error(err);
        } else {
          MessagePlugin.error(JSON.stringify(err));
        }
        break;
    }
  }
  // 常用方法封装
  get<T>(url: string, params?: object): Promise<ResultData<T>> {
    return this.service.get(url, { params });
  }
  post<T>(url: string, params?: object): Promise<ResultData<T>> {
    return this.service.post(url, params);
  }
  patch<T>(url: string, params?: object): Promise<ResultData<T>> {
    return this.service.patch(url, params);
  }
  put<T>(url: string, params?: object): Promise<ResultData<T>> {
    return this.service.put(url, params);
  }
  delete<T>(url: string, params?: object): Promise<ResultData<T>> {
    return this.service.delete(url, { params });
  }
  deletes<T>(url: string, params?: any): Promise<ResultData<T>> {
    return this.service.delete(url, { data: params });
  }
}

// 导出一个实例对象
export default new RequestHttp(config);
